﻿using System;
using System.Collections.Generic;
using System.Text;

namespace ycdlib
{
	/// <summary>
	/// パスを表すクラス
	/// </summary>
	internal class Path
	{
		//	パスのノード
		private class Node
		{
			public string name;
			public int depth;
			public Node parent;

			/// <summary>
			/// コンストラクタ
			/// </summary>
			public Node ()
			{
				name = null;
				depth = 0;
				parent = null;
			}
		}


		#region フィールド

		/// <summary>
		///	パスのノードのリスト。
		/// </summary>
		private List<Node> pathNode;

		#endregion


		/// <summary>
		/// 指定した位置のディレクトリ名を取得できる
		/// </summary>
		/// <param name="index"></param>
		/// <returns></returns>
		public string this[int index]
		{
			get
			{
				return pathNode[index].name;
			}
		}


		/// <summary>
		/// パスの深さを取得できる
		/// </summary>
		public int Depth
		{
			get { return pathNode.Count; }
		}


		/// <summary>
		///	コンストラクタ
		/// </summary>
		/// <param name="s">パス文字列ね</param>
		public Path ( string path )
		{
			//	セパレータ文字列は、'/'で統一。
			char[] sepa = { '/' };

			pathNode = Perse( path, sepa );
		}

		/// <summary>
		/// パースする
		/// </summary>
		/// <param name="path"></param>
		/// <param name="sepa"></param>
		/// <returns></returns>
		private List<Node> Perse( string path, char[] sepa )
		{
			//	パス用のリストを確保
			List<Node> result = new List<Node>();

			//	ルートノード
			Node rootNode = new Node();
			rootNode.name = "ROOT";

			//	入力が空だったら、なんもないよ
			if( string.IsNullOrEmpty(path) )	return null;


			//	パスをセパレータ文字列で分割
			string[] __paths = path.Split( sepa );

			Node __wp = null;
			Node __parentPathNode = null;

			int I = __paths.Length;
			for( int i=0 ; i<I ; ++i )
			{
				string __s = __paths[i];
				if( string.IsNullOrEmpty(__s) ) continue;
				if( ".".Equals( __s ) ) continue;
				if( "..".Equals( __s) )
				{
					if( __wp!=null )//&& __wp.parent !=null )
					{
						__wp = __wp.parent;
						result.RemoveAt( result.Count-1 );
					}
					continue;
				}

				//	パスオブジェクトを作成する
				__parentPathNode = __wp;
				__wp = new Node();
				__wp.name = __s;
				__wp.depth = result.Count;
				__wp.parent = __parentPathNode;
				//	パスリストに追加
				result.Add( __wp );
			}
			return result;
		}



		public override string ToString()
		{
			if( pathNode==null ) return string.Empty;
			StringBuilder sb = new StringBuilder();
			int I = pathNode.Count;
			for( int i=0 ; i<I ; ++i )
			{
				sb.Append( "/" ).Append( pathNode[i].name );
			}
			return sb.ToString();
		}



		public string ToString( int depth, char sepa )
		{
			if( pathNode==null || pathNode.Count<depth ) return string.Empty;
			StringBuilder sb = new StringBuilder();
			int I = pathNode.Count;
			for( int i=depth ; i<I ; ++i )
			{
				sb.Append( sepa ).Append( pathNode[I] );
			}
			return sb.ToString();
		}
	}
}
